package com.woniuxy.owner.util;


import com.woniuxy.common.utils.ResponseEnum;
import com.woniuxy.common.utils.ResponseUtil;
import com.woniuxy.owner.config.MinioConfig;
import io.minio.*;
import io.minio.http.Method;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class MinioUtil {

    @Resource
    private MinioClient minioClient;

    @Resource
    private MinioConfig minioConfig;  // 注入配置类

    /**
     * 上传文件到指定桶
     * @param file 上传的文件
     * @param bucketName 存储桶名称
     * @return 包含文件URL的响应对象
     * @throws Exception 上传异常
     */
    public ResponseUtil uploadFile(MultipartFile file, String bucketName) throws Exception {
        // 1. 检查桶是否存在，不存在则创建
        boolean isBucketExists = minioClient.bucketExists(BucketExistsArgs.builder()
                .bucket(bucketName)
                .build());
        if (!isBucketExists) {
            log.info("存储桶 {} 不存在，正在创建...", bucketName);
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        }

        // 2. 生成唯一文件名
        String fileName = generateUniqueFileName(file.getOriginalFilename());

        // 3. 上传文件到MinIO
        try (InputStream inputStream = file.getInputStream()) {
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(fileName)
                            .contentType(file.getContentType())
                            .stream(inputStream, file.getSize(), -1)  // -1表示不限制分片大小
                            .build());
        } catch (Exception e) {
            log.error("文件上传到MinIO失败: {}", e.getMessage());
            throw new Exception("文件上传失败: " + e.getMessage());
        }

        // 4. 获取文件访问URL
        String fileUrl = getFileUrl(bucketName, fileName);
        log.info("文件上传成功，URL: {}", fileUrl);

        return ResponseUtil.get(ResponseEnum.OK, fileUrl );
    }

    /**
     * 使用默认桶上传文件
     * @param file 上传的文件
     * @return 包含文件URL的响应对象
     * @throws Exception 上传异常
     */
    public ResponseUtil uploadFile(MultipartFile file) throws Exception {
        return uploadFile(file, minioConfig.getBucket());
    }

    /**
     * 获取文件访问URL
     * @param bucketName 存储桶名称
     * @param objectName 文件对象名
     * @return 文件访问URL
     */
    public String getFileUrl(String bucketName, String objectName) {
        try {
            // 使用预签名URL（有效期7天）
            return minioClient.getPresignedObjectUrl(
                    GetPresignedObjectUrlArgs.builder()
                            .method(Method.GET)
                            .bucket(bucketName)
                            .object(objectName)
                            .expiry(7, TimeUnit.DAYS)  // 7天有效期
                            .build());
        } catch (Exception e) {
            log.error("获取文件预签名URL失败: {}", e.getMessage());
            throw new RuntimeException("无法生成文件访问URL", e);
        }
    }

    /**
     * 删除文件
     * @param bucketName 存储桶名称
     * @param objectName 文件对象名
     * @return 操作结果
     */
    public ResponseUtil deleteFile(String bucketName, String objectName) {
        try {
            minioClient.removeObject(
                    RemoveObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .build());
            log.info("文件删除成功: {}/{}", bucketName, objectName);
            return ResponseUtil.get(ResponseEnum.OK);
        } catch (Exception e) {
            log.error("删除文件失败: {}/{}", bucketName, objectName, e);
            return ResponseUtil.get(ResponseEnum.Fail, e.getMessage());
        }
    }

    /**
     * 生成唯一文件名
     * @param originalFilename 原始文件名
     * @return 唯一文件名
     */
    private String generateUniqueFileName(String originalFilename) {
        if (originalFilename == null || originalFilename.isEmpty()) {
            throw new IllegalArgumentException("文件名不能为空");
        }
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        return System.currentTimeMillis() + "_" + suffix;
    }
}